package com.training.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.training.dto.UserDto;
import com.training.entity.Address;
import com.training.entity.Role;
import com.training.entity.RoleUser;
import com.training.entity.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * @BelongsProject: environment-supervision
 * @BelongsPackage: com.training.controller
 * @Author: Tianyu Han
 * @CreateTime: 2024-06-27  10:14
 * @Description: TODO
 * @Version: 1.0
 */
@RestController()
@RequestMapping("/user")
@Slf4j
@Tag(name = "用户管理" )
public class UserController {


    @Operation(summary = "获取用户列表")
    @GetMapping
    public SaResult getUserList(@RequestParam Integer page, @RequestParam Integer pageSize,
                                @RequestParam(defaultValue = "") String province,
                                @RequestParam(defaultValue = "") String city,
                                @RequestParam(defaultValue = "") String role,
                                @RequestParam(defaultValue = "") String name) {
        List<User> userList = Db.lambdaQuery(User.class)
                .like(User::getRealName, name)
                .eq(User::getIsValid, 1)
                .list();
        // 查询地址表，找到对应的地址，并查询角色，筛选
        userList = userList.stream().filter(e -> {
            Address address = Db.lambdaQuery(Address.class).eq(Address::getId, e.getAddressId())
                    .like(Address::getProvince, province).like(Address::getCity, city).one();
            log.warn("address: {}", address);
            Role role1 = Db.lambdaQuery(RoleUser.class).eq(RoleUser::getUserId, e.getId()).oneOpt()
                    .map(roleUser -> Db.lambdaQuery(Role.class).eq(Role::getId, roleUser.getRoleId()).like(Role::getRoleName, role ).one())
                    .orElse(null);
            log.warn("role: {}", role1);
            return role1 != null  && address != null;

        }).toList();
        //组装成UserDto
        List<UserDto> userDtos = userList.stream().map(e -> {
                    Address address = Db.lambdaQuery(Address.class).eq(Address::getId, e.getAddressId()).one();
                    Role role1 = Db.lambdaQuery(RoleUser.class).eq(RoleUser::getUserId, e.getId()).oneOpt()
                            .map(roleUser -> Db.lambdaQuery(Role.class).eq(Role::getId, roleUser.getRoleId()).one())
                            .orElse(null);
                    return UserDto.builder()
                            .id(e.getId())
                            .code(e.getCode())
                            .telNum(e.getTelNum())
                            .realName(e.getRealName())
                            .birthday(e.getBirthday())
                            .address(address)
                            .role(role1)
                            .sex(e.getSex())
                            .email(e.getEmail())
                            .build();
                }).toList();
        log.warn("userList: {}", userList);
        int start = (page - 1) * pageSize;
        int end = Math.min(page * pageSize, userDtos.size());
        int total = userDtos.size();
        List<UserDto> users = userDtos.subList(start, end);
        Map<String, Object> data = Map.of("total", total, "data", users);
        return SaResult.ok("获取用户信息成功").setData(data);
    }

    @PostMapping
    @Transactional
    @Operation(summary = "添加用户")
    public SaResult addUser(@RequestBody UserDto userDto) {
        // 先添加地址
        Address address = userDto.getAddress();
        Db.save(address);
        // 添加用户
        User user = User.builder()
                .code(userDto.getCode())
                .telNum(userDto.getTelNum())
                .realName(userDto.getRealName())
                .birthday(userDto.getBirthday())
                .addressId(address.getId())
                .email(userDto.getEmail())
                .sex(userDto.getSex())
                .password("123456")
                .build();
        Db.save(user);
        // 添加角色
        Role role = userDto.getRole();
        RoleUser roleUser = RoleUser.builder()
                .roleId(role.getId())
                .userId(user.getId())
                .build();
        Db.save(roleUser);
        return SaResult.ok("添加用户成功");
    }

    @PutMapping
    @Transactional
    @Operation(summary = "修改用户")
    public SaResult updateUser(@RequestBody UserDto userDto) {
        // 先修改地址
        Address address = userDto.getAddress();
        Db.updateById(address);
        // 修改用户
        User user = User.builder()
                .id(userDto.getId())
                .code(userDto.getCode())
                .telNum(userDto.getTelNum())
                .realName(userDto.getRealName())
                .birthday(userDto.getBirthday())
                .addressId(address.getId())
                .sex(userDto.getSex())
                .email(userDto.getEmail())
                .build();
        Db.updateById(user);
        // 修改角色
        // 如果角色没变
        Role role = userDto.getRole();
        RoleUser roleUser = Db.lambdaQuery(RoleUser.class)
                .eq(RoleUser::getUserId, user.getId()).one();
        if (!roleUser.getRoleId().equals(role.getId())) {
            roleUser.setRoleId(role.getId());
            Db.updateById(roleUser);
        }
        return SaResult.ok("修改用户成功");
    }

    @DeleteMapping("/{id}")
    @Transactional
    @Operation(summary = "删除用户")
    public SaResult deleteUser(@PathVariable String id) {
        User user = Db.lambdaQuery(User.class).eq(User::getId, id).one();
        if (user == null) {
            return SaResult.error("用户不存在");
        }
        // 查询角色是否为管理员
        RoleUser roleUser = Db.lambdaQuery(RoleUser.class).eq(RoleUser::getUserId, user.getId()).one();
        if (roleUser.getRoleId().equals("1")) {
            return SaResult.error("管理员不能删除");
        }
        // 修改用户的is_valid字段
        user.setIsValid(0);
        Db.updateById(user);
        StpUtil.logout(user.getId());
        return SaResult.ok("删除用户成功");
    }
}
